package com.ccteam.fluidmusic.ui.dialog

import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.ResultReceiver
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DiffUtil
import com.ccteam.fluidmusic.R
import com.ccteam.fluidmusic.databinding.BitrateSelectItemBinding
import com.ccteam.fluidmusic.databinding.DialogSelectBitrateBinding
import com.ccteam.fluidmusic.fluidmusic.common.utils.BitrateTrackCommandReceiver
import com.ccteam.fluidmusic.fluidmusic.common.utils.BitrateTrackData
import com.ccteam.fluidmusic.fluidmusic.common.utils.TrackInfo
import com.ccteam.fluidmusic.utils.getColor
import com.ccteam.fluidmusic.view.adapters.ViewBindViewHolder
import com.ccteam.fluidmusic.view.adapters.viewbinding.ViewBindingAdapter
import com.ccteam.fluidmusic.widget.SNACKBAR_BOTTOM
import com.ccteam.fluidmusic.widget.snackbar
import com.ccteam.fluidmusic.ui.MainActivityViewModel
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.color.MaterialColors
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch

/**
 * @author Xiaoc
 * @since 2021/4/22
 *
 * 选择音质比特率的底部弹窗Fragment
 */
@AndroidEntryPoint
class SelectBitrateDialog: BottomSheetDialogFragment() {

    private var _binding: DialogSelectBitrateBinding? = null
    private val binding get() = _binding!!

    private val mainActivityViewModel by activityViewModels<MainActivityViewModel>()

    private lateinit var adapter: SelectBitrateRVAdapter

    private var renderIndex: Int = -1

    companion object{
        val differCallback = object: DiffUtil.ItemCallback<BitrateTrackData>(){

            override fun areItemsTheSame(oldItem: BitrateTrackData, newItem: BitrateTrackData): Boolean {
                return false
            }

            override fun areContentsTheSame(oldItem: BitrateTrackData, newItem: BitrateTrackData): Boolean {
                return false
            }

        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = DialogSelectBitrateBinding.inflate(inflater,container,false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        adapter = SelectBitrateRVAdapter{
            mainActivityViewModel.setCurrentBitrate(resultReceiver,it,renderIndex)
        }
        binding.rvBitrate.adapter = adapter

        viewLifecycleOwner.lifecycleScope.launch {
            mainActivityViewModel.commandGetBitrate(resultReceiver)
        }

        binding.containerCancel.setOnClickListener {
            dismiss()
        }
    }

    private val resultReceiver = object: ResultReceiver(Handler(Looper.getMainLooper())){

        override fun onReceiveResult(resultCode: Int, resultData: Bundle?) {
            if(resultCode == BitrateTrackCommandReceiver.SELECT_BITRATE_COMMAND_SUCCESS){
                val trackInfoList = resultData?.getParcelableArrayList<TrackInfo>(
                    BitrateTrackCommandReceiver.COMMAND_SELECT_BITRATE
                ) ?: listOf()

                if(trackInfoList.isNotEmpty()){
                    renderIndex = trackInfoList[0].renderIndex
                    val bitrateList = trackInfoList[0].bitrateList

                    adapter.submitList(bitrateList)
                } else {
                    requireActivity().findViewById<TextView>(R.id.FluidMusicBottomBar).snackbar(
                        R.string.description_select_bitrate_fail_no_bitrate,
                        SNACKBAR_BOTTOM
                    ).show()
                    dismiss()
                }

            } else if(resultCode == BitrateTrackCommandReceiver.SELECT_BITRATE_COMMAND_FAIL){
                requireActivity().findViewById<TextView>(R.id.FluidMusicBottomBar).snackbar(
                    R.string.description_select_bitrate_fail,
                    SNACKBAR_BOTTOM
                ).show()
                dismiss()
            } else if(resultCode == BitrateTrackCommandReceiver.UPDATE_BITRATE_COMMAND_SUCCESS){
                requireActivity().findViewById<TextView>(R.id.FluidMusicBottomBar).snackbar(
                    R.string.description_update_bitrate_success,
                    SNACKBAR_BOTTOM
                ).show()
                dismiss()
            } else if(resultCode == BitrateTrackCommandReceiver.UPDATE_BITRATE_COMMAND_FAIL){
                requireActivity().findViewById<TextView>(R.id.FluidMusicBottomBar).snackbar(
                    R.string.description_update_bitrate_fail,
                    SNACKBAR_BOTTOM
                ).show()
            }
        }
    }

    class SelectBitrateRVAdapter(
        private val callback: (BitrateTrackData) -> Unit
    ): ViewBindingAdapter<BitrateSelectItemBinding,
            SelectBitrateRVAdapter.BitrateSelectViewHolder,BitrateTrackData>(differCallback){

        inner class BitrateSelectViewHolder(
            binding: BitrateSelectItemBinding
        ): ViewBindViewHolder<BitrateSelectItemBinding>(binding){
            var item: BitrateTrackData? = null

            init {
                binding.root.setOnClickListener {
                    item?.let {
                        callback(it)
                    }
                }
            }
        }

        override fun createViewBinding(parent: ViewGroup, viewType: Int): BitrateSelectViewHolder {
            return BitrateSelectViewHolder(
                BitrateSelectItemBinding.inflate(LayoutInflater.from(parent.context), parent,false)
            )
        }

        override fun bindItem(
            holder: BitrateSelectViewHolder,
            position: Int,
            item: BitrateTrackData,
            payloads: MutableList<Any>
        ) {
            holder.item = item
            parseBitrateInfo(holder,item)
            if(item.selected){
                holder.binding.tvBitrateName.setTextColor(MaterialColors.getColor(holder.binding.tvBitrateName,R.attr.colorPrimary))
                holder.binding.containerSelectBitrate.backgroundTintList = ColorStateList.valueOf(
                    holder.binding.containerSelectBitrate.getColor(R.color.defaultSelectColor)
                )
            } else {
                holder.binding.tvBitrateName.setTextColor(MaterialColors.getColor(holder.binding.tvBitrateName,R.attr.colorOnSurface))
                holder.binding.containerSelectBitrate.backgroundTintList = ColorStateList.valueOf(Color.TRANSPARENT)
            }
        }

        /**
         * 根据Bitrate解析为不同的文本描述
         */
        private fun parseBitrateInfo(holder: BitrateSelectViewHolder, item: BitrateTrackData){

            when{
                item.bitrate < 0 ->{
                    holder.binding.tvBitrateName.text = holder.binding
                        .tvBitrateName.context.getString(R.string.description_bitrate_auto)
                }
                item.bitrate in 0..140800 ->{
                    holder.binding.tvBitrateName.text = holder.binding
                        .tvBitrateName.context.getString(R.string.description_bitrate_nq)
                }
                item.bitrate <= 352000 ->{
                    holder.binding.tvBitrateName.text = holder.binding
                        .tvBitrateName.context.getString(R.string.description_bitrate_hq)
                }
                else ->{
                    holder.binding.tvBitrateName.text = holder.binding
                        .tvBitrateName.context.getString(R.string.description_bitrate_sq)
                }
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()

        _binding = null
    }
}